package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.GameUtil;
import com.neutech.maplestory.util.ImageUtil;

import java.awt.*;
import java.awt.event.KeyEvent;
/**
 * @author 小李要吃鱼
 * @date 2021-01-27 18:20
 */
public class Hero extends AbstractMapleStoryObject{
    public static Image [] imgs = new Image[100];
    static {
        for (int i = 0; i < 4; i++) {
            imgs[i] = ImageUtil.getImages("hero_right_stand" + i);
        }
        for (int i = 4; i < 8; i++) {
            imgs[i] = ImageUtil.getImages("hero_left_stand" + (i - 4));
        }
        for (int i = 8; i < 13; i++) {
            imgs[i] = ImageUtil.getImages("hero_right_walk" + (i - 8));
        }
        for (int i = 13; i < 18; i++) {
            imgs[i] = ImageUtil.getImages("hero_left_walk" + (i - 13));
        }

        imgs[18] = ImageUtil.getImages("hero_right_prone");
        imgs[19] = ImageUtil.getImages("hero_left_prone");
        imgs[20] = ImageUtil.getImages("hero_right_jump");
        imgs[21] = ImageUtil.getImages("hero_left_jump");


        for (int i = 22; i < 26; i++){
            imgs[i] = ImageUtil.getImages("hero_right_shoot" + (i - 22));
        }
        for (int i = 26; i < 30; i++){
            imgs[i] = ImageUtil.getImages("hero_left_shoot" + (i - 26));
        }

    }

    public MapleStoryClient msc;

    public Hero(){}

    public Hero(MapleStoryClient msc,int x,int y){
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.speed = Constant.HERO_SPEED;
        this.width = imgs[0].getWidth(null);
        this.height = imgs[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;
    }
    /**
     *  一直加的计数器
     */
    private int count;
    /**
     *  计算当前画第几张图
     */
    private int step;
    /**
     * 左右的开关
     */
    public boolean left,right,down,jump,shoot;
    @Override
    public void draw(Graphics g) {
        switch (dir){
            case RIGHT:
                switch (action){
                    case STAND:
                        //  right stand
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[step++ % 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //  right walk
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 8], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 8], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[18],x - 7,y + 30,null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[20],x ,y ,null);
                        break;
                    default:
                        break;
                    case SHOOT:
                        //  right shoot
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 22], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 22], x, y, null);
                        }
                        break;
                }

                break;

            case LEFT:
                switch (action){
                    case STAND:
                        //  left stand

                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[step++ % 4 + 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //  left walk
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 13], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 13], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[19],x - 7,y + 30,null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[21],x ,y ,null);
                        break;
                    case SHOOT:
                        //  right shoot
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 26], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 26], x, y, null);
                        }
                        break;
                    default:
                        break;
                }


        }

        move();
    }

    @Override
    public void move() {
        if (left){
            x -= speed;
            this.action = Action.WALK;
        }
        if (right){
            x += speed;
            this.action = Action.WALK;
        }
        if (jump){
            jump();
        }
        if (shoot){
            shoot();
        }
        outofBound();

        confirmStatus();

    }
//     射击持续时长的变量
    private int  shootCount = 0;
//    射击的方法
    private void shoot(){
        shootCount++;
        if (shootCount % 10 == 0){
            shoot = false;
            Arrow arrow;
            if (dir ==  Direction.RIGHT){
                arrow = new Arrow(x+this.width,y+this.height / 2 + 8,dir);
            }else{
                arrow = new Arrow(x,y+this.height / 2 + 8,dir);
            }

            msc.arrows.add(arrow);
        }

    }

    private double v0 = Constant.INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height;
    private double t = 0.5;
    /**
     * 跳的方法
     */
    private void jump(){
        // vt = v0 + gt  竖直上抛
        vt = v0 - g * t;
        delta_height = v0 * t;
        v0 = vt;
        y -= delta_height;
        // 自由落体的截数据位置
        if (y >= 500){
            jump = false;
            v0 = Constant.INIT_JUMP_SPEED;
            vt = 0.0;
            y = 500;
        }

    }

    /**
     * 根据当前人物的左右开关，确定人物的方向
     */
    private void confirmStatus(){
        if (left && !right){
            this.dir = Direction.LEFT;
            if (jump){
                this.action = Action.JUMP;
            }
        }else if (right && !left){
            this.dir = Direction.RIGHT;
            if (jump){
                this.action = Action.JUMP;
            }
        }else if (down){
            this.action = Action.PRONE;
        }else if (jump){
            this.action = Action.JUMP;
        }
        if (shoot){
            this.action = Action.SHOOT;
        }
        //  都按下或都不按下
        else {
            this.action = Action.STAND;
        }


    }


    /**
     * 按键的方法
     * @param e 键盘事件对象
     */
    public void keyPressed(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_A:
                left = true;
                break;

            case KeyEvent.VK_D:
                right = true;
                break;
            case KeyEvent.VK_S:
                down = true;
                break;
            case KeyEvent.VK_K://  跳跃
                jump = true;
                break;
            case KeyEvent.VK_J://  射击
                shoot = true;
                break;
            default:
                break;
        }
    }

    /**
     * 抬起按键的方法
     * @param e 键盘事件
     */
    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()){
            case KeyEvent.VK_A:
                left = false;
                break;

            case KeyEvent.VK_D:
                right = false;
                break;
            case KeyEvent.VK_S:
                down = false;
                break;
//            case KeyEvent.VK_J:
//                shoot = false;
//                break;
            default:
                break;
        }


    }
//    人物出界判断
    private void outofBound(){
        if (this.x <= 0){
            this.x = 0;
        }
        if (this.x >= Constant.GAME_WIDTH - this.width){
            this.x = Constant.GAME_WIDTH - this.width;
        }
    }
}
